﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TheVerge.Base.Platform;

namespace TheVerge.Base.Models
{
    public class VMPodcasts : VMEntries<VMPodcast>
    {
        private IAudioPlayer _Player;

        public event EventHandler PlayStateChanged = delegate { };
        
        public VMPodcasts(IAudioPlayer player)
        {
            _Player = player;
            _Player.PlayStateChanged += Player_PlayStateChanged;
        }

        #region VMEntris Overrides
        public override string DisplayName { get { return "Podcasts"; } }

        protected override void LoadMoreImp(Action<APIResponse<VMPodcast>> OnFinished, Action<Exception> OnError)
        {
            API.GetPodcasts(LastPageLoaded + 1,
                entries => OnFinished(GeneratePodcasts(entries, this, _Player)),
                OnError);
        }
        #endregion

        private void Player_PlayStateChanged(object sender, AudioPlayStateChangedEventArgs e)
        {
            Notify(() => CurrentAudioDuration);
            Notify(() => CurrentAudioPosition);
            Notify(() => PlayState);
            PlayStateChanged(this, null);
        }

        public TimeSpan CurrentAudioPosition { get { return _Player.Position; } }

        public TimeSpan CurrentAudioDuration { get { return _Player.Duration; } }

        public VMPodcast ActivePodcast
        {
            get { return GetValue(() => ActivePodcast); }
            set { SetValue(value, () => ActivePodcast); }
        }

        public AudioPlayState PlayState { get { return _Player.CurrentState; } }

        public bool IsActiveTrack(VMPodcast podcast)
        {
            return _Player.IsActiveTrack(podcast);
        }
        
        public void Play(VMPodcast podcast)
        {
            ActivePodcast = podcast;
            _Player.Play(podcast);
        }

        public void PlayPause(VMPodcast podcast)
        {
            if (_Player.IsPlaying(podcast))
            {
                _Player.Pause();
            }
            else
            {
                Play(podcast);
            }
        }

        public void FastForward(VMPodcast vMPodcast)
        {
            if (_Player.IsPlaying(vMPodcast))
            {
                _Player.FastForward();
            }
        }

        public void Rewind(VMPodcast vMPodcast)
        {
            if (_Player.IsPlaying(vMPodcast))
            {
                _Player.Rewind();
            }
        }

        public void Seek(TimeSpan ts)
        {
            _Player.Seek(ts);
        }

        private static APIResponse<VMPodcast> GeneratePodcasts(APIResponse<PodcastEntry> entries, VMPodcasts parent, IAudioPlayer player)
        {
            var response = new APIResponse<VMPodcast>()
            {
                Count = entries.Count,
                CurrentPage = entries.CurrentPage,
                TotalPages = entries.TotalPages
            };

            response.Entries = entries.Entries.Select(e => new VMPodcast(e, parent, player)).ToArray();

            return response;
        }
    }

    public class VMPodcast : AVM, IEntry
    {
        private PodcastEntry _BackingEntry;
        private VMPodcasts _Parent;
        private IAudioPlayer _Player;

        public string Author { get { return _BackingEntry.Author; } }
        public string Body { get { return _BackingEntry.Body; } }
        public int Id { get { return _BackingEntry.Id; } }
        public string Mp3Link { get { return _BackingEntry.Mp3Link; } }
        public int NumberOfComments { get { return _BackingEntry.NumberOfComments; } }
        public DateTime PublishedOn { get { return _BackingEntry.PublishedOn; } }
        public string Title { get { return _BackingEntry.Title; } }

        public bool IsPlaying
        {
            get { return _Player.IsPlaying(this); }
        }

        public TimeSpan Duration
        {
            get { return _Parent.CurrentAudioDuration; }
        }

        public TimeSpan Position
        {
            get { return _Parent.CurrentAudioPosition; }
        }

        public VMPodcast(PodcastEntry entry, VMPodcasts parent, IAudioPlayer player)
        {
            _BackingEntry = entry;
            _Parent = parent;
            _Player = player;
            _Player.PlayStateChanged += _Player_PlayStateChanged;
        }

        public void Select()
        {
            _Parent.ActivePodcast = this;
        }

        public void Play()
        {
            _Parent.Play(this);
            Notify(() => IsPlaying);
        }

        public void PlayPause()
        {
            _Parent.PlayPause(this);
        }

        public void Rewind()
        {
            _Parent.Rewind(this);
        }

        public void FastForward()
        {
            _Parent.FastForward(this);
        }

        private void _Player_PlayStateChanged(object sender, AudioPlayStateChangedEventArgs e)
        {
            Notify(() => IsPlaying);
            Notify(() => Duration);
            Notify(() => Position);
        }

        public void Seek(TimeSpan ts)
        {
            _Parent.Seek(ts);
        }
    }
}
